package grpcsvc

import (
	"context"
	"encoding/hex"
	"fmt"
	"publiclib/grpcutil"
	"time"

	pb "generatorserver/internal/protobuf"
	"generatorserver/module/generator"

	"github.com/google/uuid"
	log "github.com/sirupsen/logrus"
)

// server is used to implement GeneratorServer.
type generatorServer struct {
	pb.UnimplementedGeneratorServer
}

// NewList implements GeneratorServer
func (s *generatorServer) NewList(ctx context.Context, req *pb.NewListReq) (*pb.NewListResp, error) {
	log.Infof("Received req: %+v", req)
	if len(req.ServerId) == 0 {
		return nil, grpcutil.Error(grpcutil.InvalidArgument, "serverId value is invalid.")
	}
	if req.Size > 5000 || req.Size <= 0 {
		return nil, grpcutil.Error(grpcutil.InvalidArgument, "size value is invalid.")
	}
	_now := time.Now()
	bn := fmt.Sprintf("%s%.2d", _now.Format("060102150405"), req.ServerId[0])
	list := make([]string, 0, req.Size)
	var i int32 = 0
	switch req.Gtype {
	case pb.GeneratorType_CARD_SECRET:
		for ; i < req.Size; i++ {
			list = append(list, generator.NewCardSecret(req.ServerId[0]).String())
		}
	case pb.GeneratorType_UNIVERSAL:
		for ; i < req.Size; i++ {
			list = append(list, uuid.NewString())
		}
	case pb.GeneratorType_UNIVERSAL_HEX:
		for ; i < req.Size; i++ {
			uid := uuid.Must(uuid.NewRandom())
			bid := [16]byte(uid)
			list = append(list, hex.EncodeToString(bid[:]))
		}
	case pb.GeneratorType_LICENSE:
		lics := generator.GenerateLicenses(req.ServerId[0], int(req.Size))
		for _, lic := range lics {
			list = append(list, lic.String())
		}
	}
	return &pb.NewListResp{
		Data: &pb.ListData{
			List:        list,
			BatchNumber: bn,
		},
	}, nil
}

// Validation implements GeneratorServer
func (s *generatorServer) Validation(ctx context.Context, req *pb.ValidationReq) (*pb.ValidationResp, error) {
	log.Infof("Received req: %+v", req)
	if len(req.Value) == 0 {
		return nil, grpcutil.Error(grpcutil.InvalidArgument, "ValidationReq value is invalid.")
	}
	switch req.Gtype {
	case pb.GeneratorType_CARD_SECRET:
		_, err := generator.ParseCardSecret(req.Value)
		if err != nil {
			log.Error("ParseCardSecret fail,", err)
			return nil, grpcutil.Error(grpcutil.InvalidArgument, "ValidationReq value is invalid.")
		}
	case pb.GeneratorType_UNIVERSAL, pb.GeneratorType_UNIVERSAL_HEX:
		_, err := uuid.Parse(req.Value)
		if err != nil {
			log.Error("uuid Parse fail,", err)
			return nil, grpcutil.Error(grpcutil.InvalidArgument, "ValidationReq value is invalid.")
		}
	case pb.GeneratorType_LICENSE:
		_, err := generator.ParseLicense(req.Value)
		if err != nil {
			log.Error("ParseLicense fail,", err)
			return nil, grpcutil.Error(grpcutil.InvalidArgument, "ValidationReq value is invalid.")
		}
	}
	return &pb.ValidationResp{
		Succeeded: true,
	}, nil
}
